Onboarding

Getting Started

Install prerequisites, verify Codex CLI availability, and run sync/async SDK tasks with retries and session persistence.

1. Prerequisites

  • Python 3.10+.
  • Codex CLI installed and available on PATH as codex.
  • Authenticated Codex CLI session (or use CODEX_API_KEY per call).
# verify Python
python3 --version

# verify codex
codex --version

# verify login status
codex login status

2. Repository Structure

codex_local_sdk/
  __init__.py
  client.py
  models.py
  session_store.py
  exceptions.py
examples/
tests/
README.md

3. First SDK Run (Sync)

from codex_local_sdk import CodexExecRequest, CodexLocalClient, SandboxMode

client = CodexLocalClient()
result = client.run(
    CodexExecRequest(
        prompt="Summarize this repository and suggest three next steps.",
        sandbox=SandboxMode.READ_ONLY,
    ),
    timeout_seconds=120,
)
print(result.final_message)

4. Async Run

import asyncio
from codex_local_sdk import CodexExecRequest, CodexLocalClient


async def main() -> None:
    client = CodexLocalClient()
    result = await client.run_async(
        CodexExecRequest(prompt="Summarize this repository in async mode."),
        timeout_seconds=120,
    )
    print(result.final_message)


asyncio.run(main())

5. Configure Retry/Backoff

Retry policy applies to sync command execution (run, resume, and wrappers that call them).

from codex_local_sdk import CodexLocalClient, RetryPolicy

client = CodexLocalClient(
    retry_policy=RetryPolicy(
        max_attempts=3,
        initial_backoff_seconds=0.5,
        backoff_multiplier=2.0,
        max_backoff_seconds=4.0,
        retry_on_exit_codes=None,
        jitter_ratio=0.2,
        max_total_retry_seconds=10.0,
        retry_on_timeouts=True,
    )
)

6. Persistent Session Store

Persist logical session names to Codex thread IDs across process restarts.

from codex_local_sdk import CodexLocalClient, JsonFileSessionStore

store = JsonFileSessionStore(".codex_sessions.json")
client = CodexLocalClient(session_store=store)

session, _ = client.start_thread(
    prompt="Create an initial plan.",
    session_name="repo-plan",
)

follow_up = client.resume(
    prompt="Continue with implementation details.",
    session_name="repo-plan",
    last=False,
    json_output=True,
)
print(follow_up.turn_status)

7. Observability Hook

from codex_local_sdk import CodexClientEvent, CodexLocalClient


def on_event(event: CodexClientEvent) -> None:
    print(event.type, event.operation, event.attempt, event.return_code)


client = CodexLocalClient(event_hook=on_event)

8. Use API Key per Call (Optional)

result = client.run(
    CodexExecRequest(prompt="Analyze open TODOs."),
    api_key="YOUR_CODEX_API_KEY"
)
Use secret storage for keys in CI/CD. Never hardcode credentials in committed files.

9. Known Runtime Notes

  • Without json_output=True, final message comes from plain stdout.
  • With JSON mode, final message is parsed from the last completed agent message event.
  • If CLI is unavailable, SDK raises CodexNotInstalledError.
  • If command exits non-zero and raise_on_error=True, SDK raises CodexExecFailedError.
  • Async methods are first-class API methods and use asyncio-compatible process primitives.

10. Next Pages